//
//  Copy_constructor.hpp
//  learnC++
//
//  Created by liuzhibing on 2018/6/6.
//  Copyright © 2018年 yunfan.com. All rights reserved.
//

#ifndef Copy_constructor_hpp
#define Copy_constructor_hpp

#include <stdio.h>
#include <iostream>
#include <cassert>

class FractionTwo
{
private:
    int m_numerator;
    int m_denominator;
    
//    防止复制
//    我们可以通过将复制构造函数设为私有来防止我们的类的副本：
//    FractionTwo(const FractionTwo &fraction):
//    m_numerator(fraction.m_numerator), m_denominator(fraction.m_denominator){
//        std::cout << "Copy constructor called\n";
//    }
    
public:
    // Default constructor
    FractionTwo(int numerator=0, int denominator=1) :
    m_numerator(numerator), m_denominator(denominator)
    {
        assert(denominator != 0);
    }
    
    //复制构造函数（作为函数参数进行值传递时，也是调用该方法）
    FractionTwo(const FractionTwo &fraction):
    m_numerator(fraction.m_numerator), m_denominator(fraction.m_denominator){
        std::cout << "Copy constructor called\n";
    }
    
    friend std::ostream& operator<<(std::ostream& out, const FractionTwo &f1);
};

/*
 // Copy initialize an integer
 int x = 6;
 
 // Copy initialize a Fraction, will call Fraction(6, 1)
 Fraction six = Fraction(6);
 
 // Copy initialize a Fraction.  The compiler will try to find a way to convert 7 to a Fraction, which will invoke the Fraction(7, 1) constructor.
 //复制初始化
 Fraction seven = 7;
 
 
 
 
 Fraction fra(5, 3); // Direct initialize a Fraction, calls Fraction(int, int) constructor
 //复制构造函数
 就像默认的构造函数一样，如果您没有为您的类提供复制构造函数，C ++将为您创建一个公共复制构造函数。由于编译器对类的了解不多，因此默认情况下，创建的拷贝构造函数使用一种称为成员初始化的初始化方法。成员初始化仅仅意味着副本的每个成员都是直接从被复制类的成员初始化的。
 Fraction fCopy(fra);
 
 类的默认拷贝构造函数只会用被拷贝类的成员的值为拷贝类简单初始化，也就是说二者的p指针指向的内存空间是一致的。浅拷贝和深拷贝~
 
 //就像我们可以明确定义一个默认构造函数一样，我们也可以显式地定义一个复制构造函数。
 
 
 
 NOTE:
 请注意，初始化一个匿名对象，然后使用该对象直接初始化我们定义的对象需要两个步骤（一个创建匿名对象，一个调用复制构造函数）。 但是，最终结果与仅进行直接初始化相同，只需要一步。
 出于这个原因，在这种情况下，编译器可以选择不调用复制构造函数，而是直接进行初始化。 这个过程被称为elision。
 Fraction fiveThirds(Fraction(5, 3));
 The compiler may change this to:
 Fraction fiveThirds(5, 3);
 
 */


#endif /* Copy_constructor_hpp */

